package com.yeung.actions;

import com.yeung.beans.Person;
import com.yeung.beans.User;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.Reader;
import java.io.Writer;
import java.util.Arrays;
import java.util.Date;
import java.util.Map;

import static com.yeung.actions.ServiceResult.SUCCESS;

@Controller
@RequestMapping("/pojo")
/**
 * 会按照请求参数名进行匹配,以达到数据的注入
 */
@SessionAttributes(value = {"user"}, types = {String.class})
public class POJOTest {
    @RequestMapping("/test")
    public void pojo(Person person) {
        System.out.println(person);

    }

    @RequestMapping("/api")
    public void servletAPI(HttpServletRequest request,
                           HttpServletResponse response,
                           Reader reader, Writer writer) {
        System.out.println("获取到原生servlet的一些参数对象" + request);
        System.out.println(response);
        System.out.println(reader);
        System.out.println(writer);

    }

    @RequestMapping("/mv")
    public ModelAndView modelAndViewTest() {
        String viewName = SUCCESS;
        ModelAndView mv = new ModelAndView(viewName);//返回的视图
        mv.addObject("att", "this msg is from server");//返回时携带的数据

        return mv;
    }

    /**
     * 请求域数据:
     * spring会解析 这个map,创建一个隐含的模型对象作为模型数据的存储容器
     * 将其中的值加入到请求域中携带回去,也可以访问其中的数据
     * <p>
     * 同时也可使使用modelMap 和model spring都会对其进行解析
     *
     * @param map
     * @return
     */
    @RequestMapping("/mv2")
    public String modelMapTest(Map<String, Object> map, ModelMap modelMap, Model model) {
        System.out.println(map.getClass().getName());//获取模型创建的map名
        map.put("names", Arrays.asList("tom", "jerry"));
        model.addAttribute("age", 23);
        modelMap.put("email", "dmlsl@qq.com");
        return SUCCESS;
    }

    /**
     * session域: 这个注解只能放在类上边,而不能放在方法上边
     *
     * @SessionAttributes(value = {"user"},types = {String.class})
     * 它表明 key=user 这个 值会同时放在请求域中也会放在session域中
     * types: 表示string类型的数据会同时放在请求域中也会放在session域中
     */
    @RequestMapping("/mv3")
    public String sessionTest(ModelMap map) {
        map.put("user", "yueung");
        map.put("time", new Date());
        return SUCCESS;

    }

    /**
     * @param id
     * @param map
     * @ModelAttribute 注解的方法会在该controller下所有目标执行前被SpringMvc调用!!!
     * <p>
     * modelAttribute 会执行一段业务代码,将其中的User u放到请求域中
     * spring 在进行数据注入的时候,就不会new 一个新的user而是使用已存在的进行赋值,
     * 而是对已经存在user对象进行赋值(常用于更新操作)
     */
    @ModelAttribute
    public void getUser(@RequestParam(value = "id", required = false) Integer id,
                        Map<String, Object> map) {
        if (id != null) {
//            模拟从数据库获取该对象
            User u = new User(1);
            u.setAge(12);
            u.setUserName("tom");
            u.setEmail("tom@atguigu.com");
            u.setPass("123456");
            System.out.println("原始值:" + u);
            // 这个key命名需要与使用的目标方法的处的命名一致
            //或者在参数上指定获取哪一个key 如:@ModelAttribute("user")
            map.put("user", u);
        }
    }

    @RequestMapping("/modelAttribute")
//    @ModelAttribute("user")//不一定非要, 针对特别指定对象
    public String testModelAttribute(@ModelAttribute("user") User user) {
        System.out.println("修改" + user);
        return SUCCESS;
    }


}
